package com.junmo.oauth.module.system.service;


import com.junmo.oauth.module.system.dao.SysRoleRepository;
import com.junmo.oauth.module.system.entity.SysRole;
import com.junmo.oauth.utils.BeanUtil;
import com.junmo.oauth.utils.R;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class SysRoleService {
    // 1、先引入实体类管理器
    @PersistenceContext
    private EntityManager entityManager;

    private SysRoleRepository sysRoleRepository;

    public List<SysRole> findAll(){
        return sysRoleRepository.findAll();
    }

    public Page<SysRole> page(SysRole search, Pageable pageable) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("roleName", ExampleMatcher.GenericPropertyMatcher::contains)
                .withMatcher("rOleCode", ExampleMatcher.GenericPropertyMatcher::contains)
                ;
        Example<SysRole> example = Example.of(search,matcher);
        return sysRoleRepository.findAll(example,pageable);
    }

    @Transactional
    public R create(SysRole entity) {
        SysRole repoEntoty = sysRoleRepository.findByRoleCode(entity.getRoleCode());
        if(repoEntoty!=null) return R.error("角色名已存在！！！");
        SysRole returnEntity=sysRoleRepository.save(entity);
        if(returnEntity==null) return R.error("新建角色失败！！！");
        return R.success("success");
    }
    @Transactional
    public R edit(SysRole entity) {
        entity = BeanUtil.copyNullProperties(entity,sysRoleRepository.getOne(entity.getRoleId()));
        SysRole repoEntoty=sysRoleRepository.save(entity);
        if(repoEntoty==null) return R.error("角色不存在！！！");
        return R.success("success");
    }
    @Transactional
    public R deleteByIds(List<Number> ids) {
        ids.removeAll(Collections.singleton(null));
        if(CollectionUtils.isEmpty(ids)) return R.error("error");
        List<Long> list=ids.stream().map(id-> Long.valueOf(String.valueOf(id ))).collect(Collectors.toList());
        sysRoleRepository.deleteAll( sysRoleRepository.findAllById(list) );
        return R.success("success");
    }
    @Transactional
    public R assignResource(Number roleId ,List<Number> resourceIds) {
        resourceIds.removeAll(Collections.singleton(null));
        StringBuilder getResourceIdsSqlWhere = new StringBuilder(" in ( ");
        resourceIds.forEach(resourceId->{
            getResourceIdsSqlWhere.append(resourceId+", ");
        });
        getResourceIdsSqlWhere.deleteCharAt(getResourceIdsSqlWhere.lastIndexOf(","));
        getResourceIdsSqlWhere.append(" ) ");
        String getResourceIdsSql = "WITH RECURSIVE temp AS " +
                " ( " +
                "   SELECT * FROM sys_resource r WHERE r.resource_id  "+getResourceIdsSqlWhere.toString() +
                "   UNION ALL" +
                "   SELECT r.* FROM sys_resource r,temp t WHERE t.parent_id = r.resource_id" +
                " ) select resource_id from temp";
        Query getResourceIdsQuery = entityManager.createNativeQuery(getResourceIdsSql);
        List getResourceIds= getResourceIdsQuery.getResultList();
        Set ids = new HashSet<>();
        for (Object obj :getResourceIds) {
            long id = Long.valueOf(String.valueOf(obj));
            ids.add( id );
        }
        String deleteSql = "delete from sys_role_resource where role_id="+ roleId;
        String insertSql = "insert into sys_role_resource (role_id,resource_id) select "+roleId+" as 'role_id',resource_id from sys_resource ";
        StringBuilder insertSqlWhere = new StringBuilder(" where resource_id in ( ");
        ids.forEach(resourceId->{
            insertSqlWhere.append(resourceId+", ");
        });
        insertSqlWhere.deleteCharAt(insertSqlWhere.lastIndexOf(","));
        insertSql += insertSqlWhere.toString()+" ) ";
        Query deleteQuery = entityManager.createNativeQuery(deleteSql);
        Query insertQuery = entityManager.createNativeQuery(insertSql);
        int deleteResult= deleteQuery.executeUpdate();
        int insertResult= insertQuery.executeUpdate();
        return R.success("成功！！！！");
    }

}
